// 题意：给定n*m的棋盘（n <= 150, m <= 10），里面有坏点，问用2×3的格子覆盖，
//       不能覆盖坏点，最多能覆盖几个。
//
// 题解：状压dp可以搞定。黑书上好像用三进制的什么方法，没细看。
//       我的做法是用二进制表示一行的状态，1表示坏点或者覆盖有格子。
//       然后枚举前两行的状态dfs转移到当前行。
//       可以贴加一个哨兵行方便处理。然后有一个大大提高效率的剪枝，
//       就是在dfs找到未被加入vector的有效状态的时候才把它push进去。
//       复杂度不太好估计，远小于O(n*(2^m)^2)，因为有效状态不一定能满。
//
// run: time $exec < bugs.in9
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>

int const maxn = 152;
int const maxm = 11;
int const max_len = 1 << maxm;

int map[maxn];
short f[2][max_len][max_len];
int n, m, k, current_row, ans, row;

bool vis[2][max_len];
bool pvis[max_len];

std::vector<std::vector<int> > vaild_state(maxn);

bool row_state_check(int row, int s)
{
	if (map[row] & s) return false;
	int continous_one = 0;
	for (; s; s /= 2) {
		if (s & 1) continous_one++;
		else {
			if (continous_one && continous_one < 2) return false;
			continous_one = 0;
		}
	}
	return true;
}

bool check_put_horizontally(int delta, int prow, int now)
{
	return !((delta & prow) || (delta & now));
}

bool check_put_vertically(int delta, int pprow, int prow, int now)
{
	return !((delta & pprow) || (delta & prow) || (delta & now));
}

void dfs(int col, int pprow, int prow, int nprow, int now, int add)
{
	if (col == m) {
		// expand vaild but not pushed state in dfs,
		// reduce much invaild state.
		if (!vis[current_row][now]) {
			vis[current_row][now] = true;
			vaild_state[row].push_back(now);
		}
		if (!vis[current_row ^ 1][nprow]) {
			vis[current_row ^ 1][nprow] = true;
			vaild_state[row - 1].push_back(nprow);
		}
		f[current_row][nprow][now] = std::max(f[current_row][nprow][now],
				short(f[current_row ^ 1][pprow][prow] + add));
		ans = std::max(ans, (int)f[current_row][nprow][now]);
	}
	if (col >= m) return;

	// ***
	// ***
	int delta = (1 << col) | (1 << (col + 1)) | (1 << (col + 2));
	if (col + 2 < m && check_put_horizontally(delta, prow, now))
		dfs(col + 3, pprow, prow, nprow + delta, now + delta, add + 1);

	// **
	// **
	// **
	delta ^= 1 << (col + 2);
	if (col + 1 < m && check_put_vertically(delta, pprow, prow, now))
		dfs(col + 2, pprow, prow, nprow + delta, now + delta, add + 1);

	// left empty
	dfs(col + 1, pprow, prow, nprow, now, add);
}

int main()
{
	int T;
	std::scanf("%d", &T);
	while (T--) {
		std::scanf("%d%d%d", &n, &m, &k);
		for (int i = 0; i <= n; i++) {
			map[i] = 0;
			vaild_state[i].clear();
		}
		map[0] = (1 << m) - 1;

		for (int i = 0, x, y; i < k; i++) {
			std::scanf("%d%d", &x, &y);
			map[x] += 1 << (y - 1);
		}

		int len = 1 << m;
		std::memset(vis, 0, sizeof(vis));
		// init vaild_state
		vaild_state[0].push_back(map[0]);
		for (int state = 0; state < len; state++)
			if (row_state_check(1, state)) {
				vaild_state[1].push_back(state | map[1]);
				vis[0][state | map[1]] = true;
			}
		/*
		std::printf("--------\n");
		for (auto i : vaild_state) std::printf("%d\n", (int)i.size());
		std::printf("--------\n");
		*/

		std::memset(f, 0, sizeof(f));
		current_row = ans = 0;
		for (row = 2; row <= n; row++) {
			current_row ^= 1;
			for (int i = 0; i < len; i++)
				vis[current_row][i] = false;
			for (int ppi = 0; ppi < (int)vaild_state[row - 2].size(); ppi++) {
				int pprow = vaild_state[row - 2][ppi];
				for (int pi = 0; pi < (int)vaild_state[row - 1].size(); pi++) {
					int prow = vaild_state[row - 1][pi];
					dfs(0, pprow, prow, prow, map[row], 0);
				}
			}
		}

		std::printf("%d\n", ans);
	}
}

